home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xmris / apple.c next >
C/C++ Source or Header  |  1995-05-03  |  19KB  |  808 lines

  1. /*{{{  (C) 1992 Nathan Sidwell*/
  2. /*****************************************************************************
  3.             X M R I S V1.01
  4.             ---------------
  5.             (C) 1992 Nathan Sidwell
  6.  
  7. This program is copyright (C) 1992 Nathan Sidwell. This software and documentation
  8. is in the public domain. Permission is granted to distribute and compile
  9. verbatim copies of this software for non-commercial, non-profit use,
  10. without fee. The software may be modified, provided that both the above copyright
  11. notice and this permission notice appear.
  12.  
  13. No guarantee is given as to the robustness or suitability of this
  14. software for your computer.
  15.  
  16. Nathan Sidwell  INMOS UK |                 | nathan@inmos.co.uk       DoD#0390
  17. *****************************************************************************/
  18. /*}}}*/
  19. #include "xmris.h"
  20. /*{{{  APPLE *apple_search(x, y, width, height, found)*/
  21. extern APPLE *apple_search FUNCARGLIST((x, y, width, height, found))
  22. int       x       FUNCARGSEP  /* x coord start */
  23. int       y       FUNCARGSEP  /* y coord start */
  24. unsigned  width   FUNCARGSEP  /* width of box */
  25. unsigned  height  FUNCARGSEP  /* hieght of box */
  26. unsigned  found   FUNCARGTERM /* already found ones */
  27. /*
  28.  * looks for an apple in the specified box
  29.  * and returns a ptr to it, if found
  30.  */
  31. {
  32.   unsigned  i;
  33.   APPLE     *aptr;
  34.   
  35.   for(aptr = apple.list, i = 0; i != apple.apples; i++, aptr++, found >>= 1)
  36.     if(!(found & 1) && aptr->pixel.x + aptr->push - x >= 0 &&
  37.     aptr->pixel.x + aptr->push - x < width &&
  38.     aptr->pixel.y - y >= 0 && aptr->pixel.y - y < height)
  39.       return aptr;
  40.   return NULL;
  41. }
  42. /*}}}*/
  43. /*{{{  int apple_stop(mptr, cptr)*/
  44. extern int apple_stop FUNCARGLIST((mptr, cptr))
  45. MONSTER   *mptr FUNCARGSEP
  46. CELL      *cptr FUNCARGTERM
  47. /*
  48.  * sees if the monster is about to walk into an apple
  49.  * returns 0 if clear, 1 if stopped
  50.  * sets mptr->pause & mptr->stop as required
  51.  * the apples and other monsters are altered
  52.  * if they're pushed about
  53.  * called before we've moved the monster
  54.  */
  55. {
  56.   unsigned  stop;
  57.   unsigned  pause;
  58.   pause = stop = 0;
  59.   switch(mptr->dir)
  60.   {
  61.     /*{{{  case 0: (up)*/
  62.     case 0:
  63.     {
  64.       if(mptr->offset.y == -VEL_Y)
  65.     /*{{{  walked into apple?*/
  66.     {
  67.       unsigned  i;
  68.       APPLE     *aptr;
  69.       int       px, py;
  70.             
  71.       px = mptr->pixel.x;
  72.       py = mptr->pixel.y;
  73.       for(aptr = apple.list, i = apple.apples; i--; aptr++)
  74.         {
  75.           if(aptr->pixel.x + aptr->push - px < CELL_WIDTH &&
  76.           aptr->pixel.x + aptr->push - px > -CELL_WIDTH &&
  77.           py - aptr->pixel.y > 0 &&
  78.           py - aptr->pixel.y <= CELL_HEIGHT)
  79.         {
  80.           stop = 1;
  81.           break;
  82.         }
  83.         }
  84.     }
  85.     /*}}}*/
  86.       break;
  87.     }
  88.     /*}}}*/
  89.     /*{{{  case 1: (down)*/
  90.     case 1:
  91.     {
  92.       unsigned  i;
  93.       APPLE     *aptr;
  94.       int       px, py;
  95.     
  96.       px = mptr->pixel.x;
  97.       py = mptr->pixel.y;
  98.       for(aptr = apple.list, i = apple.apples; i--; aptr++)
  99.     {
  100.       if(aptr->pixel.x + aptr->push - px < CELL_WIDTH &&
  101.           aptr->pixel.x + aptr->push - px > -CELL_WIDTH &&
  102.           aptr->pixel.y + apple_sizes[aptr->state].offset.y - py <=
  103.           CELL_HEIGHT &&
  104.           aptr->pixel.y + apple_sizes[aptr->state].offset.y - py > 0)
  105.         {
  106.           stop = 1;
  107.           break;
  108.         }
  109.     }
  110.       break;
  111.     }
  112.     /*}}}*/
  113.     /*{{{  case 2: (left)*/
  114.     case 2:
  115.     {
  116.       unsigned  found;
  117.       int       x, y;
  118.       int       width;
  119.       APPLE     *final;
  120.       
  121.       found = 0;
  122.       final = NULL;
  123.       width = VEL_X;
  124.       x = mptr->pixel.x - CELL_WIDTH + 1 - width;
  125.       y = mptr->pixel.y - CELL_HEIGHT + VEL_Y;
  126.       /*{{{  look for apple*/
  127.       for(;;)
  128.       {
  129.     APPLE     *aptr;
  130.     CELL      *cptr;
  131.           
  132.     aptr = apple_search(x, y,
  133.         width + CELL_WIDTH / 2, 2 * (CELL_HEIGHT - VEL_Y), found);
  134.     if(!aptr)
  135.       break;
  136.     else if(aptr->state > 3 || aptr->push ||
  137.         aptr->pixel.x - width < PIXELX(0, 0))
  138.       {
  139.         stop = 1;
  140.         break;
  141.       }
  142.     else if(aptr->state == 2 && ((mptr->type != 1 && mptr->type != 4) ||
  143.         (aptr->offset.x < 0 &&
  144.         (cptr = BOARDCELL(aptr->cell.x, aptr->cell.y +
  145.         (aptr->offset.y <= 0)))->depths[2] > aptr->offset.x &&
  146.           !cptr[-1].visit)))
  147.       break;
  148.     else
  149.       {
  150.         final = aptr;
  151.         found |= 1 << (aptr - apple.list);
  152.         width = aptr->pixel.x - x + 1;
  153.         aptr->maypush = width;
  154.         x = aptr->pixel.x - CELL_WIDTH + 1 - width;
  155.         if(aptr->state != 2 && aptr->offset.y > 0 &&
  156.         apple_search(x, aptr->pixel.y - aptr->offset.y +
  157.         CELL_HEIGHT, width, aptr->offset.y, found))
  158.           {
  159.         stop = 1;
  160.         break;
  161.           }
  162.         y = aptr->pixel.y - CELL_HEIGHT + VEL_Y;
  163.         if(!width || aptr->state == 2)
  164.           break;
  165.       }
  166.       }
  167.       /*}}}*/
  168.       if(found && !stop)
  169.     {
  170.       /*{{{  check if against monster*/
  171.       if(width)
  172.         {
  173.           unsigned  i;
  174.           MONSTER   *mptr;
  175.           MONSTER   *list;
  176.                 
  177.           list = NULL;
  178.           for(mptr = monster.list, i = monster.monsters; i--; mptr++)
  179.         {
  180.           if(mptr->pixel.x - x >= 0 &&
  181.               mptr->pixel.x - x < width + CELL_WIDTH &&
  182.               mptr->pixel.y - y >= 0 &&
  183.               mptr->pixel.y - y < 2 * (CELL_HEIGHT - VEL_Y))
  184.             {
  185.               if(mptr->type == 1)
  186.             {
  187.               if(mptr->dir & 2 ||
  188.                   mptr->pixel.x - x >= width + CELL_WIDTH / 2)
  189.                 stop = 1;
  190.             }
  191.               else if(mptr->pixel.x - x >= width + CELL_WIDTH / 2)
  192.             /*(EMPTY*/;
  193.               else if(mptr->type == 4)
  194.             stop = 1;
  195.               else if(mptr->type == 0)
  196.             {
  197.               CELL      *cptr;
  198.                 
  199.               cptr = BOARDCELL(mptr->cell.x, mptr->cell.y);
  200.               if(cptr->depths[2] <= mptr->offset.x - width ||
  201.                   ((cptr->depths[1] || cptr->depths[0]) &&
  202.                   mptr->offset.x >= 0))
  203.                 {
  204.                   mptr->list = list;
  205.                   list = mptr;
  206.                   mptr->push = -1;
  207.                 }
  208.               else
  209.                 stop = 1;
  210.             }
  211.             }
  212.         }
  213.           if(final->state < 2)
  214.         final->list = list;
  215.         }
  216.       /*}}}*/
  217.       if(!stop)
  218.       {
  219.         pause = 1;
  220.         /*{{{  push the apples*/
  221.         {
  222.           unsigned  i;
  223.           APPLE     *aptr;
  224.                   
  225.           for(aptr = apple.list, i = apple.apples; i--; aptr++, found >>= 1)
  226.         if(found & 1)
  227.           aptr->push = -aptr->maypush;
  228.         }
  229.         /*}}}*/
  230.       }
  231.     }
  232.       break;
  233.     }
  234.     /*}}}*/
  235.     /*{{{  case 3: (right)*/
  236.     case 3:
  237.     {
  238.       unsigned  found;
  239.       int       x, y;
  240.       int       width;
  241.       APPLE     *final;
  242.       
  243.       found = 0;
  244.       final = NULL;
  245.       width = VEL_X;
  246.       x = mptr->pixel.x + CELL_WIDTH;
  247.       y = mptr->pixel.y - CELL_HEIGHT + VEL_Y;
  248.       /*{{{  look for apple*/
  249.       for(;;)
  250.       {
  251.     APPLE       *aptr;
  252.           
  253.     aptr = apple_search(x - CELL_WIDTH / 2, y,
  254.         width + CELL_WIDTH / 2, 2 * (CELL_HEIGHT - VEL_Y), found);
  255.     if(!aptr)
  256.       break;
  257.     else if(aptr->state > 3 || aptr->push ||
  258.         aptr->pixel.x + width > PIXELX(CELLS_ACROSS - 1, 0))
  259.       {
  260.         stop = 1;
  261.         break;
  262.       }
  263.     else if(aptr->state == 2 && ((mptr->type != 1 && mptr->type != 4) ||
  264.         (aptr->offset.x > 0 &&
  265.         (cptr = BOARDCELL(aptr->cell.x, aptr->cell.y +
  266.         (aptr->offset.y <= 0)))->depths[3] < aptr->offset.x &&
  267.           !cptr[1].visit)))
  268.       break;
  269.     else
  270.       {
  271.         final = aptr;
  272.         found |= 1 << (aptr - apple.list);
  273.         width -= aptr->pixel.x - x;
  274.         aptr->maypush = width;
  275.         x = aptr->pixel.x + CELL_WIDTH;
  276.         if(aptr->state != 2 && aptr->offset.y > 0 &&
  277.         apple_search(x, aptr->pixel.y - aptr->offset.y +
  278.         CELL_HEIGHT, width, aptr->offset.y, found))
  279.           {
  280.         stop = 1;
  281.         break;
  282.           }
  283.         y = aptr->pixel.y - CELL_HEIGHT + VEL_Y;
  284.         if(!width || aptr->state == 2)
  285.           break;
  286.       }
  287.       }
  288.       /*}}}*/
  289.       /*{{{  check if against monster*/
  290.       if(found && width)
  291.     {
  292.       unsigned  i;
  293.       MONSTER   *mptr;
  294.       MONSTER   *list;
  295.         
  296.       list = NULL;
  297.       for(mptr = monster.list, i = monster.monsters; i--; mptr++)
  298.         {
  299.           if(mptr->pixel.x - x >= -CELL_WIDTH &&
  300.           mptr->pixel.x - x < width &&
  301.           mptr->pixel.y - y >= 0 &&
  302.           mptr->pixel.y - y < 2 * (CELL_HEIGHT - VEL_Y))
  303.         {
  304.           if(mptr->type == 1)
  305.             {
  306.               if(mptr->dir & 2 ||
  307.               mptr->pixel.x - x < -CELL_WIDTH / 2)
  308.             stop = 1;
  309.             }
  310.           else if(mptr->pixel.x - x < -CELL_WIDTH / 2)
  311.             /*EMPTY*/;
  312.           else if(mptr->type == 4)
  313.             stop = 1;
  314.           else if(mptr->type == 0)
  315.             {
  316.               CELL      *cptr;
  317.         
  318.               cptr = BOARDCELL(mptr->cell.x, mptr->cell.y);
  319.               if(cptr->depths[3] >= mptr->offset.x + width ||
  320.               ((cptr->depths[1] || cptr->depths[0]) &&
  321.               mptr->offset.x <= 0))
  322.             {
  323.               mptr->list = list;
  324.               list = mptr;
  325.               mptr->push = 1;
  326.             }
  327.               else
  328.             stop = 1;
  329.             }
  330.         }
  331.         }
  332.       if(final->state < 2)
  333.         final->list = list;
  334.     }
  335.       /*}}}*/
  336.       if(found && !stop)
  337.     {
  338.       pause = 1;
  339.       /*{{{  push the apples*/
  340.       {
  341.         unsigned  i;
  342.         APPLE     *aptr;
  343.                   
  344.         for(aptr = apple.list, i = apple.apples; i--; aptr++, found >>= 1)
  345.           if(found & 1)
  346.         aptr->push = aptr->maypush;
  347.       }
  348.       /*}}}*/
  349.     }
  350.       break;
  351.     }
  352.     /*}}}*/
  353.   }
  354.   mptr->stop = stop;
  355.   mptr->pause = pause | stop;
  356.   return stop;
  357. }
  358. /*}}}*/
  359. /*{{{  void apple_under(mptr, cptr)*/
  360. extern void apple_under FUNCARGLIST((mptr, cptr))
  361. MONSTER   *mptr FUNCARGSEP
  362. CELL      *cptr FUNCARGTERM
  363. /*
  364.  * deals with walking under apples
  365.  * so that they start or stop rocking
  366.  * called after we've done the move
  367.  * only for player and muncher
  368.  */
  369. {
  370.   assert(mptr->type == 4 || mptr->type == 1);
  371.   switch(mptr->dir)
  372.   {
  373.     /*{{{  case 0: (up)*/
  374.     case 0:
  375.       if(!mptr->offset.y)
  376.     /*{{{  stop apple rocking?*/
  377.     {
  378.       unsigned  i;
  379.       APPLE     *aptr;
  380.               
  381.       for(aptr = apple.list, i = apple.apples; i--; aptr++)
  382.         {
  383.           if(aptr->pixel.x - mptr->pixel.x <= CELL_WIDTH / 2 &&
  384.          aptr->pixel.x - mptr->pixel.x >= -(CELL_WIDTH / 2) &&
  385.           aptr->state == 1 && mptr->cell.y == aptr->cell.y + 1)
  386.           {
  387.         aptr->state = 0;
  388.         aptr->count = 1;
  389.           }
  390.       }
  391.     }
  392.     /*}}}*/
  393.       break;
  394.     /*}}}*/
  395.     /*{{{  case 1: (down)*/
  396.     case 1:
  397.       if(mptr->offset.y == VEL_Y)
  398.     /*{{{  start apple rocking?*/
  399.     {
  400.       unsigned  i;
  401.       APPLE     *aptr;
  402.             
  403.       for(aptr = apple.list, i = apple.apples; i--; aptr++)
  404.         {
  405.           if(aptr->pixel.x - mptr->pixel.x <= CELL_WIDTH / 2 &&
  406.           aptr->pixel.x - mptr->pixel.x >= -(CELL_WIDTH / 2) &&
  407.           !aptr->state && mptr->cell.y == aptr->cell.y + 1)
  408.         {
  409.           aptr->state = 1;
  410.           aptr->count = APPLE_ROCK_DELAY;
  411.         }
  412.         }
  413.     }
  414.     /*}}}*/
  415.       break;
  416.     /*}}}*/
  417.     /*{{{  case 2: (left)*/
  418.     case 2:
  419.     {
  420.       unsigned  i;
  421.       APPLE     *aptr;
  422.       int       px, py;
  423.       int       cy;
  424.     
  425.       px = mptr->pixel.x;
  426.       py = mptr->pixel.y;
  427.       cy = mptr->cell.y;
  428.       /*{{{  walking under apple?*/
  429.       for(aptr = apple.list, i = apple.apples; i--; aptr++)
  430.     {
  431.       if(aptr->cell.y + 1 != cy)
  432.         /*EMPTY*/;
  433.       else if(aptr->pixel.x - px == CELL_WIDTH / 2 && !aptr->state)
  434.         {
  435.           aptr->state = 1;
  436.           aptr->count = APPLE_ROCK_DELAY;
  437.         }
  438.       else if(mptr->type == 4 && aptr->state == 1 &&
  439.           aptr->pixel.x - px == -CELL_WIDTH / 2)
  440.         {
  441.           aptr->state = 0;
  442.           aptr->count = 1;
  443.         }
  444.     }
  445.       /*}}}*/
  446.       break;
  447.     }
  448.     /*}}}*/
  449.     /*{{{  case 3: (right)*/
  450.     case 3:
  451.     {
  452.       unsigned  i;
  453.       APPLE     *aptr;
  454.       int       px, py;
  455.       int       cy;
  456.     
  457.       px = mptr->pixel.x;
  458.       py = mptr->pixel.y;
  459.       cy = mptr->cell.y;
  460.       /*{{{  walking under apple?*/
  461.       for(aptr = apple.list, i = apple.apples; i--; aptr++)
  462.     {
  463.       if(aptr->cell.y + 1 != cy)
  464.         /*EMPTY*/;
  465.       else if(px - aptr->pixel.x == CELL_WIDTH / 2 && !aptr->state)
  466.         {
  467.           aptr->state = 1;
  468.           aptr->count = APPLE_ROCK_DELAY;
  469.         }
  470.       else if(mptr->type == 4  && aptr->state == 1 &&
  471.           px - aptr->pixel.x == -CELL_WIDTH / 2)
  472.         {
  473.           aptr->state = 0;
  474.           aptr->count = 1;
  475.         }
  476.     }
  477.       /*}}}*/
  478.       break;
  479.     }
  480.     /*}}}*/
  481.   }
  482.   return;
  483. }
  484. /*}}}*/
  485. /*{{{  void move_apples()*/
  486. extern void move_apples FUNCARGVOID
  487. /*
  488.  * moves all the apples
  489.  */
  490. {
  491.   APPLE     *aptr;
  492.   unsigned  i;
  493.  
  494.   for(aptr = apple.list, i = apple.apples; i--; aptr++)
  495.     {
  496.       CELL      *cptr;
  497.   
  498.       cptr = BOARDCELL(aptr->cell.x, aptr->cell.y);
  499.       if(aptr->chewed)
  500.     {
  501.       if(aptr->monsters)
  502.         add_score(squish_scores[aptr->monsters >= SQUISH_SCORES ?
  503.         SQUISH_SCORES - 1 : aptr->monsters],
  504.         aptr->pixel.x + CELL_WIDTH / 2,
  505.         aptr->pixel.y + apple_sizes[4].size.y / 2);
  506.       aptr->state = 6;
  507.     }
  508.       else
  509.     switch(aptr->state)
  510.     {
  511.       /*{{{  case 0: (static) case 1: (rock)*/
  512.       case 0: case 1:
  513.         if(aptr->push)
  514.           {
  515.         aptr->pixel.x += aptr->push;
  516.         aptr->offset.x += aptr->push;
  517.         if(aptr->offset.x < -(CELL_WIDTH / 2))
  518.           {
  519.             aptr->offset.x += CELL_WIDTH + GAP_WIDTH;
  520.             aptr->cell.x -= 1;
  521.             cptr -= 1;
  522.           }
  523.         else if(aptr->offset.x > (CELL_WIDTH / 2))
  524.           {
  525.             aptr->offset.x -= CELL_WIDTH + GAP_WIDTH;
  526.             aptr->cell.x += 1;
  527.             cptr += 1;
  528.           }
  529.         if(cptr[0].depths[1] > aptr->offset.y)
  530.           aptr->state = 2;
  531.         else if(aptr->state == 0 && cptr[CELL_STRIDE].visit)
  532.           {
  533.             aptr->state = 1;
  534.             aptr->count = APPLE_ROCK_DELAY;
  535.           }
  536.         else if(aptr->state == 1 && !cptr[CELL_STRIDE].visit)
  537.           {
  538.             aptr->state = 0;
  539.             aptr->count = 1;
  540.           }
  541.           }
  542.         if(aptr->state == 1 && !aptr->count--)
  543.           aptr->state = 2;
  544.         if(aptr->state == 2)
  545.           {
  546.         MONSTER   *mptr;
  547.                   
  548.         aptr->count = APPLE_ACC;
  549.         aptr->distance = 0;
  550.         if(!cptr[0].visit)
  551.           {
  552.             aptr->cell.y += 1;
  553.             aptr->offset.y -= CELL_HEIGHT + GAP_HEIGHT;
  554.           }
  555.         if(cptr[CELL_STRIDE].visit || cptr[0].depths[1])
  556.           /*EMPTY*/;
  557.         else if(cptr[CELL_STRIDE-1].depths[3] +
  558.             cptr[CELL_STRIDE+1].depths[2] > 0)
  559.           {
  560.             aptr->cell.x--;
  561.             aptr->offset.x += CELL_WIDTH + GAP_WIDTH;
  562.           }
  563.         else if(cptr[CELL_STRIDE-1].depths[3] +
  564.             cptr[CELL_STRIDE+1].depths[2] < 0)
  565.           {
  566.             aptr->cell.x++;
  567.             aptr->offset.x -= CELL_WIDTH + GAP_WIDTH;
  568.           }
  569.         else
  570.           {
  571.             aptr->state = 0;
  572.             aptr->list = NULL;
  573.           }
  574.         for(mptr = aptr->list; mptr; mptr = mptr->list)
  575.           {
  576.             mptr->apple = aptr;
  577.             aptr->monsters++;
  578.             aptr->distance = APPLE_FALL_SPLIT;
  579.           }
  580.           }
  581.         else
  582.           aptr->list = NULL;
  583.         break;
  584.       /*}}}*/
  585.       /*{{{  case 2: (fall)*/
  586.       case 2:
  587.       {
  588.         unsigned  j;
  589.         APPLE     *optr;
  590.         COORD     pixel;
  591.                 
  592.         /*{{{  horizontal movement*/
  593.         if(aptr->push)
  594.           {
  595.         aptr->pixel.x += aptr->push;
  596.         aptr->offset.x += aptr->push;
  597.         if(aptr->offset.x < -(CELL_WIDTH / 2))
  598.           {
  599.             aptr->offset.x += CELL_WIDTH + GAP_WIDTH;
  600.             aptr->cell.x -= 1;
  601.             cptr -= 1;
  602.           }
  603.         else if(aptr->offset.x > (CELL_WIDTH / 2))
  604.           {
  605.             aptr->offset.x -= CELL_WIDTH + GAP_WIDTH;
  606.             aptr->cell.x += 1;
  607.             cptr += 1;
  608.           }
  609.           }
  610.         else if(aptr->waspushed)
  611.           /*EMPTY*/;
  612.         else if(aptr->offset.x < 0)
  613.           {
  614.         aptr->offset.x += APPLE_VEL_X;
  615.         aptr->pixel.x += APPLE_VEL_X;
  616.         assert(aptr->offset.x <= 0);
  617.           }
  618.         else if(aptr->offset.x > 0)
  619.           {
  620.         aptr->offset.x -= APPLE_VEL_X;
  621.         aptr->pixel.x -= APPLE_VEL_X;
  622.         assert(aptr->offset.x >= 0);
  623.           }
  624.         /*}}}*/
  625.         pixel.x = aptr->pixel.x - aptr->offset.x;
  626.         pixel.y = aptr->pixel.y - aptr->offset.y;
  627.         aptr->offset.y += aptr->count;
  628.         aptr->pixel.y += aptr->count;
  629.         aptr->distance += aptr->count;
  630.         aptr->count += APPLE_ACC;
  631.         if(aptr->count > APPLE_VEL_Y)
  632.           aptr->count = APPLE_VEL_Y;
  633.         /*{{{  bashes into another?*/
  634.         {
  635.           int       x, y;
  636.                 
  637.           x = aptr->pixel.x - CELL_WIDTH;
  638.           y = pixel.y + aptr->offset.y;
  639.           for(optr = apple.list, j = apple.apples; j--; optr++)
  640.         if(optr != aptr &&
  641.             optr->pixel.x - x > 0 &&
  642.             optr->pixel.x - x < CELL_WIDTH * 2 &&
  643.             optr->pixel.y + apple_sizes[optr->state].offset.y - y > 0 &&
  644.             optr->pixel.y + apple_sizes[optr->state].offset.y - y <
  645.             CELL_HEIGHT - APPLE_VEL_Y && (optr->state ||
  646.             BOARDCELL(optr->cell.x, optr->cell.y)->visit))
  647.           {
  648.             if(optr->state < 3)
  649.               {
  650.             optr->state = 3;
  651.             optr->count = APPLE_SPLIT_DELAY;
  652.               }
  653.             optr = NULL;
  654.             break;
  655.           }
  656.         }
  657.         /*}}}*/
  658.         if(!optr)
  659.           {
  660.         aptr->state = 3;
  661.         aptr->count = APPLE_SPLIT_DELAY;
  662.           }
  663.         else if(aptr->offset.y >= cptr[0].depths[1])
  664.           {
  665.         if(drop_apple(aptr, cptr))
  666.           /*EMPTY*/;
  667.         else if(aptr->distance >= APPLE_FALL_SPLIT ||
  668.             aptr->cell.y == CELLS_DOWN - 1)
  669.           /*{{{  fell too far*/
  670.           {
  671.             aptr->state = 3;
  672.             aptr->count = APPLE_SPLIT_DELAY;
  673.             aptr->offset.y = cptr[0].depths[1];
  674.           }
  675.           /*}}}*/
  676.         else
  677.           /*{{{  only fell a short way*/
  678.           {
  679.             aptr->state = 0;
  680.             aptr->offset.y = cptr[0].depths[1];
  681.           }
  682.           /*}}}*/
  683.           }
  684.         else if(aptr->offset.y > 0 && cptr[CELL_STRIDE].depths[0])
  685.           /*{{{  fall into next cell*/
  686.           {
  687.         aptr->cell.y += 1;
  688.         aptr->offset.y -= CELL_HEIGHT + GAP_HEIGHT;
  689.         pixel.y += CELL_HEIGHT + GAP_HEIGHT;
  690.           }
  691.           /*}}}*/
  692.         /*{{{  crushed someone?*/
  693.         {
  694.           unsigned  i;
  695.           MONSTER   *mptr;
  696.           int       x, y;
  697.                   
  698.           x = pixel.x + aptr->offset.x - CELL_WIDTH + VEL_X;
  699.           y = pixel.y + aptr->offset.y - APPLE_VEL_Y;
  700.           for(mptr = monster.list, i = monster.monsters; i--; mptr++)
  701.         if(!mptr->apple && !mptr->shot && mptr->type != 5 &&
  702.             mptr->pixel.x - x > 0 &&
  703.             mptr->pixel.x - x < 2 * (CELL_WIDTH - VEL_X) &&
  704.             mptr->pixel.y - y > 0 &&
  705.             mptr->pixel.y - y < CELL_WIDTH / 2 + APPLE_VEL_Y &&
  706.             (!(mptr->type & 2) || global.state == 4 ||
  707.               aptr->monsters || mptr->chew || mptr->dir == 1 ||
  708.               (mptr->dir == 2 && mptr->pixel.x - x <
  709.             CELL_WIDTH - VEL_X + CELL_WIDTH / 2) ||
  710.               (mptr->dir == 3 && mptr->pixel.x - x >
  711.             CELL_WIDTH - VEL_X -  CELL_WIDTH / 2)))
  712.           {
  713.             if(mptr->type & 2 && !mptr->dir && !mptr->chew &&
  714.             !aptr->monsters && global.state != 4)
  715.               {
  716.             aptr->chewed = 1;
  717.             mptr->chew = 1;
  718.               }
  719.             else
  720.               {
  721.             if(mptr != &monster.list[0])
  722.               aptr->monsters++;
  723.             mptr->apple = aptr;
  724.             aptr->distance = APPLE_FALL_SPLIT;
  725.             if(!aptr->state)
  726.               {
  727.                 aptr->state = 3;
  728.                 aptr->count = APPLE_SPLIT_DELAY;
  729.               }
  730.               }
  731.           }
  732.         }
  733.         /*}}}*/
  734.         aptr->pixel.y = pixel.y + aptr->offset.y;
  735.         break;
  736.       }
  737.       /*}}}*/
  738.       /*{{{  case 3: (split)*/
  739.       case 3:
  740.         if(!aptr->count--)
  741.           {
  742.         aptr->state = 4;
  743.         aptr->count = APPLE_DECAY_DELAY;
  744.         if(aptr->monsters)
  745.           add_score(squish_scores[aptr->monsters >= SQUISH_SCORES ?
  746.               SQUISH_SCORES - 1 : aptr->monsters],
  747.               aptr->pixel.x + CELL_WIDTH / 2,
  748.               aptr->pixel.y + apple_sizes[4].size.y / 2);
  749.           }
  750.         break;
  751.       /*}}}*/
  752.       /*{{{  case 4: (decay)*/
  753.       case 4:
  754.         if(!aptr->count--)
  755.           {
  756.         aptr->state = 5;
  757.         aptr->count = APPLE_ROT_DELAY;
  758.           }
  759.         break;
  760.       /*}}}*/
  761.       /*{{{  case 5: (rot)*/
  762.       case 5:
  763.         if(!aptr->count--)
  764.           aptr->state = 6;
  765.         break;
  766.       /*}}}*/
  767.       /*{{{  default:*/
  768.       default:
  769.         assert(0);
  770.       /*}}}*/
  771.     }
  772.       aptr->waspushed = aptr->push;
  773.       aptr->push = 0;
  774.     }
  775.   return;
  776. }
  777. /*}}}*/
  778. /*{{{  APPLE *spawn_apple(cx, cy, ox, oy)*/
  779. extern APPLE *spawn_apple FUNCARGLIST((cx, cy, ox, oy))
  780. int       cx FUNCARGSEP
  781. int       cy FUNCARGSEP
  782. int       ox FUNCARGSEP
  783. int       oy FUNCARGTERM
  784. /*
  785.  * spawns a new apple in state 0
  786.  */
  787. {
  788.   APPLE     *aptr;
  789.  
  790.   assert(apple.apples != APPLES);
  791.   aptr = &apple.list[apple.apples++];
  792.   aptr->state = 0;
  793.   aptr->cell.x = cx;
  794.   aptr->cell.y = cy;
  795.   aptr->offset.x = ox = ox / APPLE_VEL_X * APPLE_VEL_X;
  796.   aptr->offset.y = oy;
  797.   aptr->count = 1;
  798.   aptr->old_pixel.x = aptr->pixel.x = PIXELX(cx, ox);
  799.   aptr->old_pixel.y = aptr->pixel.y = PIXELY(cy, oy);
  800.   aptr->distance = 0;
  801.   aptr->monsters = 0;
  802.   aptr->push = 0;
  803.   aptr->chewed = 0;
  804.   aptr->old_state = 7;
  805.   return aptr;
  806. }
  807. /*}}}*/
  808.